/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tolls;

import avenue.MyWindowEvent;
import avenue.Session;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import model.DBManager;
import model.Vehicle;
import model.Card;
import model.Collection;
import model.Payment;
import model.Program;
import model.ProgramRate;
import model.Station;
import model.VehicleCategory;

/**
 *
 * @author Aggelos
 */
public class CollectTollForm extends javax.swing.JFrame
{

    EntityManager em;
    //Query vehicleQuery, progRateQuery;
    // List vehicleLIST;
    // List vList = null;
    Vehicle veh;
    Card card;
    Double newBalanceOfCard;
    ProgramRate pr; 
    Station st;
    Payment payment;
    JFrame thisFrame;
    double oldAmount;

    /**
     * Creates new form CollectTollForm
     */
    public CollectTollForm()
    {
        em = DBManager.em;
        if (!em.getTransaction().isActive())
          {
            em.getTransaction().begin();
          }
        initComponents();

        st=retrieveStationByID();
       // System.out.println(st.getDescription());
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents()
    {

        regNumTextField = new javax.swing.JTextField();
        passButton = new javax.swing.JButton();
        cardBarCodeTextField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel3 = new javax.swing.JLabel();
        balanceTextField = new javax.swing.JTextField();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel5 = new javax.swing.JLabel();
        confirmButton = new javax.swing.JButton();
        payCardButton = new javax.swing.JButton();
        jLabel6 = new javax.swing.JLabel();
        last30DaysLBL = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        passCostTextField = new javax.swing.JTextField();
        jSeparator3 = new javax.swing.JSeparator();
        cancelButton = new javax.swing.JButton();
        jLabel10 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        regNumTextField.setText("555");

        passButton.setText("Διέλευση");
        passButton.setEnabled(false);
        passButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                passButtonActionPerformed(evt);
            }
        });

        cardBarCodeTextField.setText("5556");

        jLabel2.setText("Αρ. Κάρτας: ");

        jLabel1.setText("Αρ. Κυκλοφορίας: ");

        jLabel3.setText("Υπόλοιπο Κάρτας: ");

        jLabel5.setFont(new java.awt.Font("Tahoma", 0, 20)); // NOI18N
        jLabel5.setText("Διέλευση Οχήματος");

        confirmButton.setText("Ταυτοποίηση Οχήματος");
        confirmButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                confirmButtonActionPerformed(evt);
            }
        });

        payCardButton.setText("Πληρωμή Κάρτας");
        payCardButton.setEnabled(false);
        payCardButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                payCardButtonActionPerformed(evt);
            }
        });

        jLabel6.setText("Διελεύσεις τις 30 προηγούμενες μέρες:");

        last30DaysLBL.setText("---");

        jLabel7.setText("Κόστος Διέλευσης:");

        passCostTextField.setText("000");

        cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/cancel.gif"))); // NOI18N
        cancelButton.setText("Άκυρο");
        cancelButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                cancelButtonActionPerformed(evt);
            }
        });

        jLabel10.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel10.setText("€");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel5)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(confirmButton)
                                .addGroup(layout.createSequentialGroup()
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(jLabel1)
                                        .addComponent(jLabel2))
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(regNumTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 143, Short.MAX_VALUE)
                                        .addComponent(cardBarCodeTextField))))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel6)
                                .addGap(18, 18, 18)
                                .addComponent(last30DaysLBL))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel7)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
                                .addComponent(passCostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(45, 45, 45))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(passButton)
                                .addGap(51, 51, 51)
                                .addComponent(cancelButton)))
                        .addGap(0, 127, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jSeparator3, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel3)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(balanceTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(23, 23, 23)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel10)
                                    .addComponent(payCardButton))
                                .addGap(0, 0, Short.MAX_VALUE))
                            .addComponent(jSeparator2)
                            .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING))
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(27, 27, 27)
                .addComponent(jLabel5)
                .addGap(18, 18, 18)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(regNumTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(cardBarCodeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(confirmButton)
                .addGap(28, 28, 28)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(last30DaysLBL))
                .addGap(18, 18, 18)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 9, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(passCostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(balanceTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(payCardButton))
                .addGap(14, 14, 14)
                .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(passButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    public Card retrieveCardById(int idC)
    {
        Card cr = em.createNamedQuery("Card.findById",
                Card.class)
                .setParameter("id", idC).getSingleResult();
        return cr;
    }

    public Card retrieveCardByBarCode(int barCodeC)
    {
        Card cr = null;
        try
          {
            cr = em.createNamedQuery("Card.findByBarcode",
                    Card.class)
                    .setParameter("barcode", barCodeC).getSingleResult();

          }
        catch (javax.persistence.NoResultException ex)
          {
            System.out.println("den iparxei carta");
            System.out.println(ex);
            return null;
          }
        return cr;
    }

    public List<Vehicle> retrieveVehicleByCard(String rNum, String crdBC)
    {
        Card c = null;
        c = retrieveCardByBarCode(Integer.parseInt(crdBC));
        String strSQL = "select j from Vehicle j where j.regNumber=:regNumber and j.id=:cardID";
        Query vehicleQuery = em.createQuery(strSQL)
                .setParameter("regNumber", rNum)
                .setParameter("cardID", c.getId());
        List vehicleLIST = vehicleQuery.getResultList();
        return vehicleLIST;
    }

    public ProgramRate retrieveProgramRateByCategoryProgramAndStations(VehicleCategory vc,
            Program p,
            Station st)
    {
        String strSQL = "select j from ProgramRate j where j.categoryId=:categoryId and j.programId=:programId and j.stationId=:stationId";
        Query prQuery = em.createQuery(strSQL)
                .setParameter("categoryId", vc)
                .setParameter("programId", p)
                .setParameter("stationId", st);
        ProgramRate pr = (ProgramRate) prQuery.getSingleResult();

        return pr;
    }
    
    public Station retrieveStationByID()
    {
      //  Session.loginUser.
        int index = Session.loginUser.getStationId().getId();
        Station s  = null;
        try
          {
            s = em.createNamedQuery("Station.findById",
                    Station.class)
                    .setParameter("id", index).getSingleResult();

          }
        catch (javax.persistence.NoResultException ex)
          {
            System.out.println("den iparxei statoion");
            System.out.println(ex);
            return null;
          }
        return s;
    }

    public int retrieveLast30Days(Card c)
    {
        Date today = new Date();
        long past30DaysMS = today.getTime() - ((long) 30 * 24 * 60 * 60 * 1000);

        Date past30Days = new Date(past30DaysMS);

        //System.out.println(past30Days);

        String strSQL = "select poj from Collection poj where poj.cardId = :cardId and poj.passTimestamp > :passTS";
        Query dateQuery = em.createQuery(strSQL)
                .setParameter("cardId", c)
                .setParameter("passTS", past30Days);

        List dList = dateQuery.getResultList();

        return dList.size();
    }

    private void confirmButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_confirmButtonActionPerformed
    {//GEN-HEADEREND:event_confirmButtonActionPerformed
        // TODO add your handling code here:

        try
          {

            List vList = null;
            vList = retrieveVehicleByCard(regNumTextField.getText(), cardBarCodeTextField.getText());

            if (vList.isEmpty())
              {
                JOptionPane.showMessageDialog(this, "Δεν Υπάρχει ταυτοποίηση",
                        "Διέλευση", JOptionPane.ERROR_MESSAGE);
                passButton.setEnabled(false);
                payCardButton.setEnabled(false);
              }
            else
              {
                payCardButton.setEnabled(true);
                card = retrieveCardByBarCode(Integer.parseInt(cardBarCodeTextField.getText()));
                balanceTextField.setText(card.getBalance().toString());

                oldAmount = card.getBalance();

                veh = (Vehicle) vList.get(0);

                pr = retrieveProgramRateByCategoryProgramAndStations(veh.getCategoryId(),
                        card.getProgramId(),
                        Session.loginUser.getStationId());

                passCostTextField.setText(pr.getRate().toString());


                int n = retrieveLast30Days(card);
                String nStr = Integer.toString(n);
                last30DaysLBL.setText(nStr);

                if (pr.getRate().doubleValue() > card.getBalance())
                  {
                    JOptionPane.showMessageDialog(this, "Η κάρτα δεν έχει επαρκές υπολοιπο",
                            "Διέλευση", JOptionPane.ERROR_MESSAGE);
                  }
                else
                  {
                    passButton.setEnabled(true);
                    if (card.getBalance() <= 10)
                      {
                        JOptionPane.showMessageDialog(this, "Η κάρτα  έχει μονο 10 € υπολοιπο",
                                "Διέλευση", JOptionPane.WARNING_MESSAGE);
                      }
                  }
              }

          }
        catch (Exception e)
          {
            JOptionPane.showMessageDialog(this, e,
                    "Διέλευση", JOptionPane.ERROR_MESSAGE);
            passButton.setEnabled(false);
            payCardButton.setEnabled(false);
            System.out.println(e);
          }
    }//GEN-LAST:event_confirmButtonActionPerformed

    private void payCardButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_payCardButtonActionPerformed
    {//GEN-HEADEREND:event_payCardButtonActionPerformed
        // TODO add your handling code here:
        //PaymentForm pf = new PaymentForm(card, vehicle);

        PaymentForm pf = new PaymentForm(card, veh);


        pf.setVisible(true);
        thisFrame = this;
        thisFrame.setEnabled(false);

        pf.addWindowListener(new WindowListener()
        {
            public void windowClosed(WindowEvent arg0)
            {
                System.out.println("Window close event occur - save button clicked");
                if (((MyWindowEvent) arg0).exitAndSave)
                  {
                    balanceTextField.setText(card.getBalance().toString());



                    thisFrame.setEnabled(true);
                  }
                else
                  {
                    System.out.println("Window close event occur -cancel button clicked");
                    thisFrame.setEnabled(true);
                  }
            }

            public void windowActivated(WindowEvent arg0)
            {
                System.out.println("Window Activated");
            }

            public void windowClosing(WindowEvent arg0)
            {
                System.out.println("Window Closing");
            }

            public void windowDeactivated(WindowEvent arg0)
            {
                System.out.println("Window Deactivated");
            }

            public void windowDeiconified(WindowEvent arg0)
            {
                System.out.println("Window Deiconified");
            }

            public void windowIconified(WindowEvent arg0)
            {
                System.out.println("Window Iconified");
            }

            public void windowOpened(WindowEvent arg0)
            {
                System.out.println("Window Opened");
            }
        });
    }//GEN-LAST:event_payCardButtonActionPerformed

    private void passButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_passButtonActionPerformed
    {//GEN-HEADEREND:event_passButtonActionPerformed
        // TODO add your handling code here:
        if (!em.getTransaction().isActive())
          {
            em.getTransaction().begin();
          }

        newBalanceOfCard = card.getBalance() - pr.getRate().doubleValue();
       // System.out.println("newBalanceOfCard " + newBalanceOfCard);
        card.setBalance(newBalanceOfCard);
        em.persist(card);



        payment = new Payment();
        payment.setCardId(card);
        em.persist(card);
        System.out.println(card.getId());

        payment.setPaymentTimestamp(new Date());
        System.out.println(new Date());

        payment.setVehicleId(veh);
        em.persist(veh);
        System.out.println(veh);

        BigDecimal oldAmountBD = BigDecimal.valueOf(oldAmount);
        payment.setOldBalance(oldAmountBD);
        System.out.println(oldAmountBD);

        payment.setPaymentAmount(pr.getRate().doubleValue());
        System.out.println(pr.getRate().doubleValue());
        
        payment.setStationId(st);
        System.out.println(st);

        em.persist(payment);
//        em.getTransaction().commit();


        Collection co = new Collection();

        co.setCardId(card);
        em.persist(card);

        co.setPassTimestamp(new Date());

        co.setTollCollected(pr.getRate());

        co.setVehicleId(veh);
        em.persist(veh);
        
        co.setStationId(st);
        em.persist(st);

        em.persist(co);
        em.getTransaction().commit();

        MyWindowEvent we = new MyWindowEvent(this, WindowEvent.WINDOW_CLOSED, true);
        for (WindowListener l : this.getWindowListeners())
          {
            l.windowClosed(we);
          }
        this.setVisible(false);
    }//GEN-LAST:event_passButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cancelButtonActionPerformed
    {//GEN-HEADEREND:event_cancelButtonActionPerformed
        // TODO add your handling code here:

        MyWindowEvent we = new MyWindowEvent(this, WindowEvent.WINDOW_CLOSED, false);
        for (WindowListener l : this.getWindowListeners())
          {
            l.windowClosed(we);
          }
        this.setVisible(false);
    }//GEN-LAST:event_cancelButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[])
    {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try
          {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
              {
                if ("Nimbus".equals(info.getName()))
                  {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                  }
              }
          }
        catch (ClassNotFoundException ex)
          {
            java.util.logging.Logger.getLogger(CollectTollForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
          }
        catch (InstantiationException ex)
          {
            java.util.logging.Logger.getLogger(CollectTollForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
          }
        catch (IllegalAccessException ex)
          {
            java.util.logging.Logger.getLogger(CollectTollForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
          }
        catch (javax.swing.UnsupportedLookAndFeelException ex)
          {
            java.util.logging.Logger.getLogger(CollectTollForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
          }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                new CollectTollForm().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField balanceTextField;
    private javax.swing.JButton cancelButton;
    private javax.swing.JTextField cardBarCodeTextField;
    private javax.swing.JButton confirmButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JLabel last30DaysLBL;
    private javax.swing.JButton passButton;
    private javax.swing.JTextField passCostTextField;
    private javax.swing.JButton payCardButton;
    private javax.swing.JTextField regNumTextField;
    // End of variables declaration//GEN-END:variables
}
